﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lumberjack.BusinessLogic
{
    public class ContestRuleEvaluator
    {

        private void pointCheck(ref int? points)
        {
            if(points == null)
            {
                points = 0;
            }
        }


        public int? x_between_two_values(string x, string ruleName, ref int? points)
        {
            pointCheck(ref points);
            int tempPoints = 0;

            double value;
            if(double.TryParse(x, out value))
            {
                List<Rule_n> res = (from s in RulesRepository.ruleN from m in RulesRepository.rule where
                                        ruleName == m.C_name && m.Id == s.Ruleid select s).ToList();
         
                foreach (Rule_n s in res)
                {
                    if (value > s.value_n && value < s.value_x)
                    {
                        tempPoints += (int)s.points;
                        break;
                    }
                }
                return points += tempPoints;
            }
            else
            {
                return tempPoints;
            }
        }

        public bool two_xs_between_values_or_equal(string x1, string x2, string ruleName1, string ruleName2, ref int? points)
        {
            pointCheck(ref points);

            double value1, value2;
            if (double.TryParse(x1,out value1) && double.TryParse(x2,out value2))
            {
                List<Rule_r> res = (from s in RulesRepository.ruleR where s.Rule.C_name == ruleName1 select s).ToList();
                int? tempVal = 0;
                foreach (Rule_r s in res)
                {
                    if ((value1 >= s.value_fn && value1 <= s.value_fx) || (value1 >= s.value_cn && value1 <= s.vlue_cx))
                    {
                        tempVal = s.points;
                    }
                }
                List<Rule_r> res2 = (from s in RulesRepository.ruleR where s.Rule.C_name == ruleName2 select s).ToList();
                int? tempVal2 = 0;
                foreach (Rule_r s in res2)
                {
                    if ((value2 >= s.value_fn && value2 <= s.value_fx) || (value2 >= s.value_cn && value2 <= s.vlue_cx))
                    {
                        tempVal2 = s.points;
                    }
                }
                if (tempVal > tempVal2)
                {
                    points += tempVal2;
                }
                else
                {
                    points += tempVal;
                }
                return true;
            }
            else
            {
                return false;
            }

          
        }

        public int? xs_equal_to_values(string x1, string x2, string ruleName, ref int? points)
        {
            pointCheck(ref points);
            int? tempPoints = 0;

            double value1, value2;
            if(double.TryParse(x1, out value1) && double.TryParse(x2, out value2))
            {
                List<Rule_n> res = (from s in RulesRepository.ruleN where s.Rule.C_name == ruleName select s).ToList();
                foreach (Rule_n s in res)
                {
                    if (value1 == s.value_n && value2 == s.value_x)
                    {
                        tempPoints = s.points;
                    }

                }
                points += tempPoints;
                return tempPoints; 
            }
            else
            {
                return tempPoints;
            }
        }

        public bool value_minus_x_above_zero(string x, string ruleName, ref int? points)
        {
            pointCheck(ref points);

            int value;
            if (int.TryParse(x, out value))
            {
                var ruleValue = (from s in RulesRepository.ruleB from m in RulesRepository.rule
                                 where ruleName == m.C_name && m.Id == s.Ruleid select s).FirstOrDefault();
                int? temp = (ruleValue.points - value);
                points += (temp < 0) ? 0 : temp;
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool x_between_two_values_or_equal(string x, string ruleName, ref int? points)
        {
            pointCheck(ref points);

            double value;
            if (double.TryParse(x, out value))
            {
                List<Rule_n> res = (from s in RulesRepository.ruleN from m in RulesRepository.rule
                                    where ruleName == m.C_name && m.Id == s.Ruleid select s).ToList();
                int? tempVal = 0;
                foreach (Rule_n s in res)
                {
                    if (value >= s.value_n && value <= s.value_x)
                    {
                        tempVal = (int)s.points;
                    }
                }
                points += tempVal;
                return true;
            }
            else
            {
                return false;
            }
        }

        public int? x_is_true(string ruleName, ref int? points)
        {
            pointCheck(ref points);
            int? tempPoints = 0;
            var ruleValue = (from s in RulesRepository.ruleB
                             from m in RulesRepository.rule
                             where ruleName == m.C_name && m.Id == s.Ruleid
                             select s).FirstOrDefault();

            points += tempPoints += ruleValue.points;
            return tempPoints;
        }

        public bool x_multiply_by_points(string x, string ruleName, ref int? points)
        {
            pointCheck(ref points);
            double value;

            if(double.TryParse(x, out value))
            {
                Rule_b res = (from s in RulesRepository.ruleB where s.Rule.C_name == ruleName select s).FirstOrDefault();
                int? temp = (res.points * Convert.ToInt32(value));
                points += temp;
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool x_fourth_fifth_competition(string x, string ruleName, ref int? points)
        {
            pointCheck(ref points);
            double value;

            if (double.TryParse(x, out value))
            {
                Rule_n res = (from s in RulesRepository.ruleN where s.Rule.C_name == ruleName select s).FirstOrDefault();
                points = res.points;
                if (value >= res.value_x)
                {
                    double? t = res.value_x - value;
                    points += (int)t;
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool x_second_competition(string x, string ruleName, ref int? points)
        {
            pointCheck(ref points);
            double value;

            if(double.TryParse(x, out value))
            { 
                Rule_n res = (from s in RulesRepository.ruleN where s.Rule.C_name == ruleName select s).FirstOrDefault();
                points += res.points;
                double? t = res.value_n - value;
                points += (int)(t * res.value_x);
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool x_is_true_multiplied(string ruleName, string multiplier, ref int? points)
        {
            pointCheck(ref points);


            var ruleValue = (from s in RulesRepository.ruleB
                             from m in RulesRepository.rule
                             where ruleName == m.C_name && m.Id == s.Ruleid
                             select s).FirstOrDefault();
 
            if(multiplier == "0")
            {
                return false;
            }

            int multi = 0;
            if(string.IsNullOrEmpty(multiplier))
            {
                multi = 1;
            }
            else
            {
                multi = Convert.ToInt32(multiplier);
            }

            points += multi * ruleValue.points;
            
            return true;
        }
    
    }
}
